# this programe is not finished
import numpy as np
import matplotlib.pyplot as plt

def solutionFunc(curSolution):
    return curSolution + np.random.uniform(low = -0.55, high=0.55)
def objectiveFunc(curSolution):
    return curSolution**2

class SA(object):
    def __init__(self,initSolution,solutionFunc,objectiveFunc, n_iter, sigma, T0, Tmin):
        self.solutionFunc = solutionFunc
        self.objectiveFunc = objectiveFunc
        self.n_iter = n_iter
        self.sigma = sigma
        self.T = T0
        self.T0 = T0
        self.Tmin = Tmin
        #random generate function         
        self.bestSolution = self.solutionFunc(initSolution)
        self.bestObjVal = self.objectiveFunc(self.bestSolution)

        self.cost = [] # storage the cost of soultion in search

    def sa(self):
        print(self.T, self.Tmin)
        t = 0
        while self.T > self.Tmin:
            for i in range(self.n_iter):
                #assume that candiate solution ~ N(self.curSolution, sigma)
                candiate = self.solutionFunc(self.bestSolution)
                candiateObjVal = self.objectiveFunc(candiate)
                
                print(candiate, candiateObjVal)
                #find optimal solution and objVal
                if candiateObjVal < self.bestObjVal:
                    self.bestObjVal, self.bestSolution = candiateObjVal,candiate
                    self.cost.append(self.bestObjVal)
                
                #wrose solution
                diff = candiateObjVal - self.bestObjVal
                metropolis = np.exp(-diff/self.T)
                if np.random.uniform(low = 0, high = 1) < metropolis:
                    self.bestObjVal, self.bestSolution = candiateObjVal,candiate
                    self.cost.append(self.bestObjVal)

            t = t+1
            self.T = self.T0/float(t+1)
        return
    def learningRate(self):
        plt.plot(self.cost)
        plt.title('learning rate')
        plt.show()
    




F = SA(10,solutionFunc, objectiveFunc, 10, 0.2, 100, 1)
F.sa()
F.learningRate()
print(F.bestSolution)
